#define _CRT_SECURE_NO_WARNINGS 1
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
typedef int DLDataType;
typedef struct DLNode
{
	DLDataType data;
	struct DLNode* prev;
	struct DLNode* next;
}DLNode; 
DLNode* DLBuyNode(DLDataType x)
{
	DLNode* new = malloc(sizeof(DLNode));
	if (new == NULL)
	{
		perror("申请空间失败");
	}
	else
	{
		new->data = x;
		new->next = new;
		new->prev = new;//此处实现的是双向循环有头链表,这样初始化(而非将已写过的其他Init()函数一样把这两个指针置空)是为了保证其循环性
	}
	return new;
}

DLNode* DLInit()
{
	DLNode* phead = DLBuyNode(0);
	return phead;
}

DLNode* DLDestroy(DLNode* phead)
{
	assert(phead);
	DLNode* pcur = phead->next;
	DLNode* pnext = pcur->next;
	while (pcur != phead)
	{
		free(pcur);
		pcur = pnext;
		pnext = pnext->next;
	}//此循环不会释放头节点
	free(phead);
	return NULL;
}

void DLPrint(DLNode* phead)
{
	assert(phead);
	DLNode* pcur = phead->next;
	while (pcur != phead)
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("\n");
}

DLNode* DLFind(DLNode* phead, int x)
{
	DLNode* pcur = phead->next;
	while (pcur != phead)
	{
		if (pcur->data == x)
		{
			return pcur;
		}
		pcur = pcur->next;
	}
	return NULL;
}

void DLPushBack(DLNode* phead, DLDataType x)//prev new phead
{
	assert(phead);
	DLNode* new = DLBuyNode(x);
	DLNode* prev = phead->prev;
	new->next = phead;
	new->prev = prev;
	prev->next = new;
	phead->prev = new;
}

void change(DLNode* p)//prev   change   p   next >>prev  p   change    next
{
	if ((p->next == p)||(p->next->next==p))//特殊情况：1、空链表，2、单节点
		return;
	else
	{
		DLNode* change = p->prev;
		DLNode* prev = change->prev;
		DLNode* next = p->next;
		prev->next = p;
		p->prev = prev;
		p->next = change;
		change->prev = p;
		change->next = next;
		next->prev = change;
	}
}

int main()
{
	//先自己生成一组链表
	//[7, 4, 10, 8, 2, 9, 6, 1 ,3, 5]
	DLNode* phead = DLInit();
	DLPushBack(phead, 7);
	DLPushBack(phead, 4);
	DLPushBack(phead, 10);
	DLPushBack(phead, 8);
	DLPushBack(phead, 2);
	DLPushBack(phead, 9);
	DLPushBack(phead, 6);
	DLPushBack(phead, 1);
	DLPushBack(phead, 3);
	DLPushBack(phead, 5);
	change(DLFind(phead, 6));
	DLPrint(phead);
	return 0;
}